package cn.getech.data.development.controller.offline;

import cn.getech.data.development.config.properties.BdpJobConfig;
import cn.getech.data.development.config.properties.DataDevelopmentConfig;
import cn.getech.data.development.constant.*;
import cn.getech.data.development.entity.*;
import cn.getech.data.development.mapper.TableInfoMapper;
import cn.getech.data.development.service.*;
import cn.getech.data.development.utils.HdfsUtil;
import cn.getech.data.development.utils.HiveTableUtil;
import cn.getech.data.development.vo.SecurityLevelVO;
import cn.getech.data.intelligence.common.exception.RRException;
import cn.getech.data.intelligence.common.utils.R;
import cn.getech.data.intelligence.common.validator.ValidatorUtils;
import cn.getech.system.center.annotation.SysLog;
import cn.getech.system.center.constant.OperationModulesEnum;
import cn.getech.system.center.constant.OperationTypeEnum;
import cn.getech.system.center.constant.module.ModuleEnum;
import cn.getech.system.center.entity.SysSecurityDataLevelEntity;
import cn.getech.system.center.service.SysSecurityDataLevelService;
import cn.getech.system.center.utils.ShiroUtils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description: 离线数据表信息
 * @author: wangzhaowen：kiss
 * @create: 2021/1/14 16:18
 * @version: 2021/1/14
 **/
@Slf4j
@Api(tags = "离线数据表信息")
@RestController
@RequestMapping("/bdp/tableInfo")
public class OfflineTableInfoController {

    @Autowired
    private TableInfoService tableInfoService;
    @Autowired
    private TableFieldInfoService tableFieldInfoService;
    @Autowired
    private DataDevelopmentConfig hiveConfig;

    @Autowired
    private BdpJobConfig bdpJobConfig;

    @Autowired
    private IAllPermissionConfigService iAllPermissionConfigService;

    @Autowired
    private UploadVersionLogService uploadVersionLogService;

    @Autowired
    private DataPermissionService dataPermissionService;

    @Autowired
    private SysSecurityDataLevelService sysSecurityDataLevelService;

    @Autowired
    private TableRelationshipService tableRelationshipService;

    @Autowired
    private BdpRealTableInfoService bdpRealTableInfoService;

    @Autowired
    private TableRegisterService tableRegisterService;
    private static Map<String, Integer> uniqueMap = Maps.newHashMap();//防止添加表重复点击

    /**
     * 删除表的数据
     */
    @ApiOperation("删除表的数据")
    @PostMapping("/truncate")
    @SysLog(value = "删除表的数据", type = OperationTypeEnum.DELETECODE,
            modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R truncate(@ApiParam(value = "{'id':1}") @RequestBody TableInfo param) {

        if (!tableInfoService.checkExistById(param.getId())) {
            throw new RRException(DataDevelopmentBizExceptionEnum.TABLE_NOT_EXIST.getMessage());
        }
        if (!tableInfoService.checkPermission(param.getId())) {
            throw new RRException(DataDevelopmentBizExceptionEnum.TABLE_PERMISSIOIN.getMessage());
        }
        TableInfo tableInfo = tableInfoService.getById(param.getId());
        List<TableFieldInfo> tableFieldInfos = tableFieldInfoService.list(new QueryWrapper<TableFieldInfo>().eq("table_id", tableInfo.getId()));
        tableInfo.setTableFieldInfos(tableFieldInfos);
        String dbName = tableInfo.getDbName();
        String tableName = tableInfo.getTableName();
        //删除数据
        HdfsUtil hdfsUtil = null;
        HiveTableUtil hiveTableUtil = new HiveTableUtil(hiveConfig.getHiveserverurl(), dbName, "hdfs", "hdfs");
        try {
            hdfsUtil = new HdfsUtil(bdpJobConfig);
            hiveTableUtil.dropTable(tableName);
            hdfsUtil.delete(HiveTableUtil.genTableLocation(dbName, tableName));
            return HiveTableDdl.createHiveTable(tableInfo, hiveConfig);
        } catch (Exception e) {
            return R.error(e.getMessage());
        } finally {
            if (null != hdfsUtil) {
                hdfsUtil.close();
            }
            hiveTableUtil.close();
        }

    }

    /**
     * 保存数据表信息
     */
    @ApiOperation("保存数据表信息")
    @PostMapping("/save")
    @SysLog(value = "保存数据表信息", type = OperationTypeEnum.ADDCODE,
            modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R save(@RequestBody TableInfo tableInfo) {
        long startTime = new Date().getTime();
        ValidatorUtils.validateEntity(tableInfo);
        //表名均为小写
        tableInfo.setTableName(tableInfo.getTableName().toLowerCase());
        if (tableInfoService.checkExistByName(tableInfo.getDbName(), tableInfo.getTableName())) {
            return R.error(DataDevelopmentBizExceptionEnum.TABLE_EXIST.getMessage());
        }
        if (CollectionUtils.isEmpty(tableInfo.getTableFieldInfos())) {
            return R.error("表中字段不能为空！");
        }
        if (!checkTableColumn(tableInfo)) {
            return R.error("表中至少有一列字段不是分区字段且字段名不可重复");
        }
        checkTableInfo(tableInfo);
        checkFieldInfo(tableInfo.getTableFieldInfos(), tableInfo.getStoreEngine());
        String key = tableInfo.getDbName() + tableInfo.getTableName();
        if (uniqueMap.containsKey(key)) {
            //防止重复提交
            return R.error("当前表在创建中，请稍后尝试");
        }
        uniqueMap.put(key, YesOrNoEnum.YES.getValue());
        try {
            tableInfo.setTenantId(ShiroUtils.getTenantId());//租户id
            R r = HiveTableDdl.createHiveTable(tableInfo, hiveConfig);
            if (null != r && r.get("code").equals(0)) {
                if (createDbTable(tableInfo, startTime)) {
                    tableInfoService.initDataPermission(tableInfo.getId(), tableInfo.getRoleId(), null);
                    return R.ok();
                } else {
                    HiveTableUtil hiveTableUtil = new HiveTableUtil(hiveConfig.getHiveserverurl(), tableInfo.getDbName(), "hdfs", "hdfs");
                    HdfsUtil hdfsUtil = null;
                    try {
                        hdfsUtil = new HdfsUtil(bdpJobConfig);
                        hiveTableUtil.dropTable(tableInfo.getTableName());
                        hdfsUtil.delete(HiveTableUtil.genTableLocation(tableInfo.getDbName(), tableInfo.getTableName()));
                    } catch (Exception e) {
                        log.error("建表失败，回滚hive表出现错误", e);
                        return R.error("建表失败，回滚hive表出现错误" + e.getMessage());
                    } finally {
                        if (null != hdfsUtil) {
                            hdfsUtil.close();
                        }
                        hiveTableUtil.close();
                    }
                }
            } else {//表创建失败
                return r;
            }
        } catch (Exception e) {
            log.error("创建表失败:", e);
            return R.error("hive表创建失败,详情如下" + e.getMessage());
        } finally {
            uniqueMap.remove(key);
        }
        return R.error("表创建失败");
    }

    /**
     * 保存数据表信息
     */
    @ApiOperation("修改数据表信息")
    @PostMapping("/update")
    @SysLog(value = "修改数据仓库信息", type = OperationTypeEnum.UPDATECODE,
            modulesType = OperationModulesEnum.TABLEMODELCODE, platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    public R update(@RequestBody TableInfo tableInfo) {
        long startTime = new Date().getTime();

        ValidatorUtils.validateEntity(tableInfo);
        //表名均为小写
        tableInfo.setTableName(tableInfo.getTableName().toLowerCase());
        if (!tableInfoService.checkExistById(tableInfo.getId())) {
            throw new RRException(DataDevelopmentBizExceptionEnum.TABLE_NOT_EXIST.getMessage());
        }
        if (CollectionUtils.isEmpty(tableInfo.getTableFieldInfos())) {
            return R.error("表中字段不能为空！");
        }
        if (!checkTableColumn(tableInfo)) {
            return R.error("表中至少有一列字段不是分区字段且字段名不可重复");
        }

        if (!tableInfoService.checkPermission(tableInfo.getId())) {  //不是自己创建的数据 才做权限校验
            if (!dataPermissionService.checkDataPermission(tableInfo.getId(),
                    PermissionTypeEnum.STORE.getType(), PermissionTypeEnum.UPDATE.getType())) {
                return R.error(DataDevelopmentBizExceptionEnum.UPDATE_NO_PERMISSION.getMessage());
            }
            if (tableInfo.getId() != null) {
                if (tableInfo.getTableFieldInfos() != null) {//存在新增字段
                    List<TableFieldInfo> filedNew = tableInfo.getTableFieldInfos()
                            .stream().filter(s -> s.getId() == null).collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(filedNew)) {
                        if (!dataPermissionService.checkDataPermission(tableInfo.getId(),
                                PermissionTypeEnum.STORE.getType(), PermissionTypeEnum.CREATE.getType())) {
                            return R.error(DataDevelopmentBizExceptionEnum.FIELD_CREATE_NO_PERMISSION.getMessage());
                        }
                    }
                    //先查询出原来的字段
                    List<TableFieldInfo> oldFieldInfos = tableFieldInfoService.list(new QueryWrapper<TableFieldInfo>().eq("table_id", tableInfo.getId()));
                    List<Integer> oldIds = oldFieldInfos.stream().map(TableFieldInfo::getId).collect(Collectors.toList());
                    //现有的字段,不是新增的字段,需要编辑的字段
                    Set<Integer> updateIds = tableInfo.getTableFieldInfos().stream()
                            .filter(s -> s.getId() != null)
                            .map(TableFieldInfo::getId).collect(Collectors.toSet());
                    List<Integer> needUpdateTableFieldIds = new ArrayList<>(updateIds);
                    List<Integer> needDelTableFieldIds = new ArrayList<>();
                    for (Integer oldId : oldIds) {
                        if (!updateIds.contains(oldId)) {
                            needDelTableFieldIds.add(oldId);
                        }
                    }
                    if (CollectionUtil.isNotEmpty(needDelTableFieldIds)) {
                        if (!dataPermissionService.checkApplyPermission(tableInfo.getId(), PermissionTypeEnum.DELETE.getType())) {
                            if (!dataPermissionService.checkDataPermission(needDelTableFieldIds,
                                    PermissionTypeEnum.STORE_FILED.getType(), PermissionTypeEnum.DELETE.getType())) {
                                return R.error(DataDevelopmentBizExceptionEnum.DELETE_FIELD_NO_PERMISSION.getMessage());
                            }
                        }
                    }
                    if (CollectionUtil.isNotEmpty(needDelTableFieldIds)) {
                        if (!dataPermissionService.checkApplyPermission(tableInfo.getId(), PermissionTypeEnum.UPDATE.getType())) {
                            if (!dataPermissionService.checkDataPermission(needUpdateTableFieldIds,
                                    PermissionTypeEnum.STORE_FILED.getType(), PermissionTypeEnum.UPDATE.getType())) {
                                return R.error(DataDevelopmentBizExceptionEnum.UPDATE_FIELD_NO_PERMISSION.getMessage());
                            }
                        }
                    }
                }
            }

        }

        checkTableInfo(tableInfo);
        checkFieldInfo(tableInfo.getTableFieldInfos(), tableInfo.getStoreEngine());
        TableInfo tableInfo1 = tableInfoService.getById(tableInfo.getId());
        if (!tableInfo1.getTableName().equalsIgnoreCase(tableInfo.getTableName())) {
            if (tableInfoService.checkExistByName(tableInfo.getDbName(), tableInfo.getTableName())) {
                return R.error(DataDevelopmentBizExceptionEnum.TABLE_EXIST.getMessage());
            }
        }
        //验证分析任务是否关联
//        tableInfoService.checkedAnalysisInfo(tableInfo.getId(),2);
        List<TableFieldInfo> tableFieldInfoList = tableFieldInfoService.list(new QueryWrapper<TableFieldInfo>().eq("table_id", tableInfo.getId()));
        tableInfo1.setTableFieldInfos(tableFieldInfoList);
        R r = updateHiveTable(tableInfo, tableInfo1, bdpJobConfig);
        if(tableInfo.getId()!=null){
            //离线表旧有目录关系不插入，换用新的插入方式
            if(tableInfo.getCateGoryIdsList()!=null){
                //先删除旧有关系
                tableInfoService.deleteCategory(tableInfo.getId());
                for(String categoryId:tableInfo.getCateGoryIdsList()){
                    Map<String,Object> map = new HashMap<>();
                    map.put("categoryId",Integer.valueOf(categoryId));
                    map.put("tableId",tableInfo.getId());
                    map.put("tenantId",ShiroUtils.getTenantId());
                    map.put("userId",ShiroUtils.getUserId().intValue());
                    map.put("datetime",new Date());
                    tableInfoService.insertRelation(map);
                }
            }
        }
        if (r.get("code").equals(0)) {
            if (updateDbTable(tableInfo, startTime)) {
                //取消生成的表策略
                //rangerDataService.updateRangerPolicyByTableId(tableInfo.getId());
                //生成表对应的角色策略
                tableInfoService.initDataPermission(tableInfo.getId(), tableInfo.getRoleId(), null);
                return R.ok();
            }
        } else {
            return r;
        }
        return R.error("修改表失败,原因是：" + r.get("msg"));
    }


    private Boolean checkTableColumn(TableInfo tableInfo) {
        int columns = 0;
        List<TableFieldInfo> listFields = tableInfo.getTableFieldInfos();
        listFields.sort(Comparator.comparingInt(TableFieldInfo::getFieldOrder));
        if (checkTableColumnIsRepeat(listFields))
            return false;
        for (TableFieldInfo fieldInfo : listFields) {
            if (YesOrNoEnum.NO.getValue().equals(fieldInfo.getIsPartition())) {
                columns++;
            }
        }
        return columns > 0;
    }

    private Boolean checkTableColumnIsRepeat(List<TableFieldInfo> listFields) {
        boolean tableColumnIsRepeat = false;
        Set<String> sets = listFields.stream().map(TableFieldInfo::getFieldName).collect(Collectors.toSet());
        if (sets.size() != listFields.size()) {
            tableColumnIsRepeat = true;
        }
        return tableColumnIsRepeat;
    }


    private Boolean createDbTable(TableInfo tableInfo, long startTime) {
        Long userId = ShiroUtils.getUserId();
        Integer tenantId = ShiroUtils.getTenantId();
        tableInfo.setTenantId(tenantId);
        tableInfo.setCreatePer(userId.intValue());
        tableInfo.setCreateTime(DateTime.now());
        tableInfo.setUpdateTime(DateTime.now());
        tableInfo.setUpdatePer(userId);
        List<AllPermissionConfig> allPermisssionList = iAllPermissionConfigService.list();
        Integer tableLevel = 0, culonm = 0, enType = 0;
        if (CollectionUtil.isNotEmpty(allPermisssionList)) {
            List<AllPermissionConfig> tableList = allPermisssionList.stream().filter(allPermissionConfig -> Objects.equals(PressionParamType.TABLE.getId(), allPermissionConfig.getPermissType())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(tableList)) {
                tableLevel = tableList.get(0).getDataPermissionId();
            }
            List<AllPermissionConfig> culonmList = allPermisssionList.stream().filter(allPermissionConfig -> Objects.equals(PressionParamType.CULONM.getId(), allPermissionConfig.getPermissType())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(tableList)) {
                culonm = culonmList.get(0).getDataPermissionId();
            }
            List<AllPermissionConfig> enStypeList = allPermisssionList.stream().filter(allPermissionConfig -> Objects.equals(PressionParamType.ENSTYPE.getId(), allPermissionConfig.getPermissType())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(tableList)) {
                enType = enStypeList.get(0).getDataPermissionId();
            }
        }
        if (tableLevel != 0) {
            tableInfo.setTableLevelId(tableLevel);
        }

        SysSecurityDataLevelEntity defaultTableService = sysSecurityDataLevelService.getDefaultTableService();
        tableInfo.setSecurityDataLevel(defaultTableService.getName());
        Boolean re = tableInfoService.save(tableInfo);
        if (re) {
            TableInfo info = tableInfoService.getOne(new QueryWrapper<TableInfo>().eq("db_name", tableInfo.getDbName())
                    .eq("table_name", tableInfo.getTableName()));
            if (info == null) {
                return false;
            } else {
                List<TableFieldInfo> list = tableInfo.getTableFieldInfos();

                for (TableFieldInfo fieldInfo : list) {
                    if (YesOrNoEnum.YES.getValue().equals(info.getStoreEngine())) {// hive 引擎
                        fieldInfo.setPrimaryKey(YesOrNoEnum.NO.getValue());
                    }
                    fieldInfo.setCreatePer(tableInfo.getCreatePer());
                    fieldInfo.setTableId(info.getId());
                    fieldInfo.setTenantId(tenantId);
                    fieldInfo.setCreateTime(DateTime.now());
                    if (0 != culonm) {
                        fieldInfo.setColcumLevelId(culonm);
                    }
                    if (0 != enType) {
                        fieldInfo.setEncyStyleId(enType);
                    }
                    fieldInfo.setSecurityDataLevel(defaultTableService.getName());
                    if (CollectionUtil.isEmpty(fieldInfo.getRelationshipes()))
                        continue;
                    for (TableRelationshipEntity shipEntity : fieldInfo.getRelationshipes()) {
                        //新增的表此时还没有元数据id
                        shipEntity.setSourceCollTableId(null);
                        shipEntity.setSourceTableId(info.getId());
                        shipEntity.setSourceTableName(info.getTableName());
                        shipEntity.setSourceFieldName(fieldInfo.getFieldName());
                    }
                    tableRelationshipService.saveBatch(fieldInfo.getRelationshipes());
                }
                tableFieldInfoService.saveBatch(list);
                Date curr = new Date();
                TableRegisterEntity registerEntity = new TableRegisterEntity();
                registerEntity.setTableInfoId(info.getId());
                registerEntity.setBatchNum(curr.getTime());
                registerEntity.setRegisterType(TableRegisterTypeEnum.OFFLINE_ADD.getCode());
                long cost = curr.getTime() - startTime;
                registerEntity.setCost(cost);
                registerEntity.setRunTime(curr);
                registerEntity.setRunUser(info.getCreatePer().longValue());
                tableRegisterService.save(registerEntity);
                // 保存物理模型  主题和类目关系
                tableInfoService.saveModelRelation(tableInfo);
                //一键入湖修改元数据采集表的关联状态
                if(tableInfo.getCollectionTableId()!=null){
                    tableInfoService.setCollectionTableId(tableInfo.getId(),tableInfo.getCollectionTableId());
                }
                return true;
            }
        } else {
            return false;
        }
    }


    private R updateHiveTable(TableInfo tableInfo, TableInfo oldTableInfo, BdpJobConfig bdpJobConfig) {
        //创建hive table
        String newTableName = tableInfo.getTableName();
        String oldTableName = oldTableInfo.getTableName();
        String jdbcUrl = hiveConfig.getHiveserverurl();
        if (StorageEngineEnum.KUDU.getCode().equals(tableInfo.getStoreEngine())) {
            //kudu 是按照修改表结构----先修改表明，再修改表结构
            jdbcUrl = hiveConfig.getKuduJdbcUrl();
            HiveTableUtil hiveTableUtil = new HiveTableUtil(jdbcUrl, tableInfo.getDbName(), "hdfs", "hdfs");
            //判断主键是否修改【如果主键修改，则需要删除表，然后新建表。数据丢失没有办法】,并且只能一个主键
            //判断分区是否修改，分区也不支持修改
            List<TableFieldInfo> tableFieldInfos1 = tableInfo.getTableFieldInfos();
            List<TableFieldInfo> tableFieldInfos2 = oldTableInfo.getTableFieldInfos();
            if (CollectionUtil.isEmpty(tableFieldInfos1) || CollectionUtil.isEmpty(tableFieldInfos2)) {
                return R.error("表不存在字段！");
            }
            List<TableFieldInfo> primaryKeyLists = tableFieldInfos1.stream().filter(o -> Objects.equals(o.getPrimaryKey(), 1)).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(primaryKeyLists)) {
                return R.error("kudu表必须含有主键！");
            }
            if (primaryKeyLists.size() > 1) {
                return R.error("kudu表的主键只能有一个！");
            }
            List<TableFieldInfo> primaryKeyLists2 = tableFieldInfos2.stream().filter(o -> Objects.equals(o.getPrimaryKey(), 1)).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(primaryKeyLists2) || primaryKeyLists2.size() > 1) {
                return R.error("以前的kudu表是错误的，请删除重新建！");
            }
            if (!Objects.equals(primaryKeyLists.get(0).getFieldName(), primaryKeyLists2.get(0).getFieldName())
                    || !Objects.equals(primaryKeyLists.get(0).getFieldType(), primaryKeyLists2.get(0).getFieldType())) {
                return R.error("不能修改kudu表的主键（字段名或者字段类型）！");
            }
            List<TableFieldInfo> newPartitions = tableFieldInfos1.stream().filter(o -> !Objects.equals(o.getIsPartition(), 0)).collect(Collectors.toList());
            List<TableFieldInfo> olderPartitions = tableFieldInfos2.stream().filter(o -> !Objects.equals(o.getIsPartition(), 0)).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(newPartitions)) {
                if (CollectionUtil.isNotEmpty(olderPartitions)) {
                    return R.error("暂不支持kudu表修改分区！");
                }
            } else {
                if (CollectionUtil.isEmpty(olderPartitions)) {
                    return R.error("暂不支持kudu表修改分区！");
                } else {
                    if (newPartitions.size() != olderPartitions.size()) {
                        return R.error("暂不支持kudu表修改分区！");
                    }
                }
            }

            //挑选表名
            if (!Objects.equals(newTableName, oldTableName)) {
                String renameSql = "ALTER TABLE " + tableInfo.getDbName() + "." + oldTableName + "  RENAME TO " + tableInfo.getDbName() + "." + newTableName;
                try {
                    hiveTableUtil.execute(renameSql);
                } catch (Exception e) {
                    log.error("RENAME tableName:", e);
                    hiveTableUtil.close();
                    return R.error("重命名kudu表异常！");
                }
            }
            //修改表结构
            List<TableFieldInfo> tableFieldInfos = tableInfo.getTableFieldInfos();
            List<TableFieldInfo> olderTbaleFields = oldTableInfo.getTableFieldInfos();
            //判断表结构是否有修改
            try {
                uploadVersionLogService.updateKuduTable(tableFieldInfos, olderTbaleFields, tableInfo, tableInfo.getDbName(), tableInfo.getTableName(), true, null, null);
            } catch (Exception e) {
                log.error("修改kudu数据仓库异常error:{}", e.getMessage());
                //还得回滚对应的表名
                if (!Objects.equals(newTableName, oldTableName)) {
                    String renameSql = "ALTER TABLE " + tableInfo.getDbName() + "." + newTableName + "  RENAME TO " + tableInfo.getDbName() + "." + oldTableName;
                    try {
                        hiveTableUtil.execute(renameSql);
                    } catch (Exception e1) {
                        log.error("RENAME tableName:", e1);
                    }
                }
                return R.error(e.getMessage());
            } finally {
                hiveTableUtil.close();
            }
        } else {
            //先删除表，再新建表，再刷数据
            HiveTableUtil hiveTableDrop = null;
            //不修改表名称
            try {
                hiveTableDrop = new HiveTableUtil(jdbcUrl, tableInfo.getDbName(), "hdfs", "hdfs");
                //此处删除只是删除表的结构不删除hdfs上的数据文件
                hiveTableDrop.dropTable(oldTableName);
            } catch (Exception e) {
                log.error("drop:", e);
                return R.error(e.getMessage());
            } finally {
                if (hiveTableDrop != null) {
                    hiveTableDrop.close();
                }
            }
            R r = HiveTableDdl.createHiveTable(tableInfo, hiveConfig);
            if (!r.isOk()) {
                HiveTableUtil hiveTableUtil = null;
                HdfsUtil hdfsUtil = null;
                try {
                    hiveTableUtil = new HiveTableUtil(jdbcUrl, tableInfo.getDbName(), "hdfs", "hdfs");
                    hdfsUtil = new HdfsUtil(bdpJobConfig);
                    hdfsUtil.rename(HiveTableUtil.genTableLocation(tableInfo.getDbName(), oldTableName), HiveTableUtil.genTableLocation(tableInfo.getDbName(), oldTableName + "_bak"));
                    R createOldTable=HiveTableDdl.createHiveTable(oldTableInfo, hiveConfig);
                    if(createOldTable.isOk()) {
                        hdfsUtil.delete(HiveTableUtil.genTableLocation(tableInfo.getDbName(), oldTableName));
                        hdfsUtil.rename(HiveTableUtil.genTableLocation(tableInfo.getDbName(), oldTableName + "_bak"), HiveTableUtil.genTableLocation(tableInfo.getDbName(), oldTableName));
                        //修改表数据后刷新表结构重新识别旧的数据
                        hiveTableUtil.repairTable(oldTableName);
                    }else{
                        return createOldTable;
                    }
                } catch (Exception ex) {
                    log.error("repairTable:", ex);
                    return R.error("修改表,恢复失败");
                } finally {
                    if (null != hdfsUtil) {
                        hdfsUtil.close();
                    }
                    if (hiveTableUtil != null) {
                        hiveTableUtil.close();
                    }
                    return r;
                }
            }
            HiveTableUtil hiveTableUtil = null;
            HdfsUtil hdfsUtil = null;
            try {
                if (!newTableName.equals(oldTableName)) {
                    hdfsUtil = new HdfsUtil(bdpJobConfig);
                    hdfsUtil.delete(HiveTableUtil.genTableLocation(tableInfo.getDbName(), newTableName));
                    hdfsUtil.rename(HiveTableUtil.genTableLocation(tableInfo.getDbName(), oldTableName), HiveTableUtil.genTableLocation(tableInfo.getDbName(), newTableName));
                }
                //创建表后会关闭链接
                hiveTableUtil = new HiveTableUtil(hiveConfig.getHiveserverurl(), tableInfo.getDbName(), "hdfs", "hdfs");
                //修改表数据后刷新表结构重新识别旧的数据
                hiveTableUtil.repairTable(newTableName);
            } catch (Exception e) {
                return R.error(e.getMessage());
            } finally {
                if (null != hdfsUtil) {
                    hdfsUtil.close();
                }
                if (hiveTableUtil != null) {
                    hiveTableUtil.close();
                }
            }
        }
        return R.ok();
    }


    private Boolean updateDbTable(TableInfo tableInfo, long startTime) {
        Long userId = ShiroUtils.getUserId();
        Integer tenantId = ShiroUtils.getTenantId();
        TableInfo tableInfo1 = tableInfoService.getById(tableInfo.getId());
        tableInfo.setCreatePer(tableInfo1.getCreatePer());
        tableInfo.setCreateTime(tableInfo1.getCreateTime());
        tableInfo.setUpdateTime(DateTime.now());
        tableInfo.setTenantId(tableInfo1.getTenantId());
        tableInfo.setUpdatePer(userId);
        List<AllPermissionConfig> allPermisssionList = iAllPermissionConfigService.list();
        Integer tableLevel = 0, culonm = 0, enType = 0;
        if (CollectionUtil.isNotEmpty(allPermisssionList)) {
            List<AllPermissionConfig> tableList = allPermisssionList.stream().filter(allPermissionConfig -> Objects.equals(PressionParamType.TABLE.getId(), allPermissionConfig.getPermissType())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(tableList)) {
                tableLevel = tableList.get(0).getDataPermissionId();
            }
            List<AllPermissionConfig> culonmList = allPermisssionList.stream().filter(allPermissionConfig -> Objects.equals(PressionParamType.CULONM.getId(), allPermissionConfig.getPermissType())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(tableList)) {
                culonm = culonmList.get(0).getDataPermissionId();
            }
            List<AllPermissionConfig> enStypeList = allPermisssionList.stream().filter(allPermissionConfig -> Objects.equals(PressionParamType.ENSTYPE.getId(), allPermissionConfig.getPermissType())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(tableList)) {
                enType = enStypeList.get(0).getDataPermissionId();
            }
        }
        if (tableLevel != 0) {
            if (!Objects.equals(tableLevel, tableInfo1.getTableLevelId())) {
                tableInfo.setTableLevelId(tableInfo1.getTableLevelId());
            } else {
                tableInfo.setTableLevelId(tableLevel);
            }
        }
        boolean re = tableInfoService.updateById(tableInfo);
        if (re) {
            TableInfo info = tableInfoService.getOne(new QueryWrapper<TableInfo>().eq("db_name", tableInfo.getDbName())
                    .eq("table_name", tableInfo.getTableName()));
            if (info == null) {
                return false;
            } else {
                //先查询出原来的字段
                List<TableFieldInfo> tableFieldInfos = tableFieldInfoService.list(new QueryWrapper<TableFieldInfo>()
                        .eq("table_id", info.getId()));
                List<TableFieldInfo> list = tableInfo.getTableFieldInfos();
                tableRelationshipService.remove(
                        new QueryWrapper<TableRelationshipEntity>()
                                .eq("source_table_id", info.getId())
                );
                SecurityLevelVO securityLevelVO = bdpRealTableInfoService.getDefaultSecurityDataLevel();
                for (TableFieldInfo fieldInfo : list) {
                    fieldInfo.setTableId(info.getId());
                    if (fieldInfo.getId() == null) {//新增的字段 创建人改为登录人
                        fieldInfo.setCreatePer(userId.intValue());
                        fieldInfo.setCreateTime(new Date());
                        fieldInfo.setTenantId(tenantId);
                        //设置修改表-新增字段的数据密级
                        fieldInfo.setColcumLevelId(securityLevelVO.getColumnLevelId());
                        fieldInfo.setSecurityDataLevel(securityLevelVO.getSecurityDataLevelName());
                    }
                    if (YesOrNoEnum.YES.getValue().equals(info.getStoreEngine())) {// hive 引擎
                        fieldInfo.setPrimaryKey(YesOrNoEnum.NO.getValue());
                    }
                    if (CollectionUtil.isNotEmpty(tableFieldInfos)) {
                        if (CollectionUtil.isNotEmpty(fieldInfo.getRelationshipes())) {
                            List<TableRelationshipEntity> temps = new ArrayList<>();
                            for (TableRelationshipEntity shipEntity : fieldInfo.getRelationshipes()) {
                                if (shipEntity.getSourceCollTableId() == null) {
                                    shipEntity.setSourceTableId(info.getId());
                                }
                                shipEntity.setSourceTableName(info.getTableName());
                                shipEntity.setSourceFieldName(fieldInfo.getFieldName());
                                List<TableRelationshipEntity> ships = tableRelationshipService.list(new QueryWrapper<TableRelationshipEntity>()
                                        .eq("relation_coll_table_id", shipEntity.getRelationCollTableId())
                                        .eq("relation_field_name", shipEntity.getRelationFieldName())
                                        .eq("source_table_name", shipEntity.getSourceTableName())
                                        .eq("source_field_name", shipEntity.getSourceFieldName())
                                        .eq(shipEntity.getSourceCollTableId() != null, "source_coll_table_id"
                                                , shipEntity.getSourceCollTableId())
                                );
                                if (CollectionUtils.isEmpty(ships)) {
                                    temps.add(shipEntity);
                                }
                            }
                            if (CollectionUtil.isNotEmpty(temps)) {
                                tableRelationshipService.saveBatch(temps);
                            }
                        }
                        List<TableFieldInfo> tableFieldInfos1 = tableFieldInfos.stream()
                                .filter(tableFieldInfo -> Objects.equals(fieldInfo.getFieldName(),
                                        tableFieldInfo.getFieldName())).collect(Collectors.toList());
                        if (CollectionUtil.isNotEmpty(tableFieldInfos1)) {
                            if (0 != culonm) {
                                if (!Objects.equals(culonm, tableFieldInfos1.get(0).getColcumLevelId())) {
                                    fieldInfo.setColcumLevelId(tableFieldInfos1.get(0).getColcumLevelId());
                                } else {
                                    fieldInfo.setColcumLevelId(culonm);
                                }
                            }
                            if (0 != enType) {
                                if (!Objects.equals(enType, tableFieldInfos1.get(0).getEncyStyleId())) {
                                    fieldInfo.setEncyStyleId(tableFieldInfos1.get(0).getEncyStyleId());
                                } else {
                                    fieldInfo.setEncyStyleId(enType);
                                }
                            }
                            continue;
                        }
                    }
                    //如果没有原来的直接设置成默认的
                    if (0 != culonm) {
                        fieldInfo.setColcumLevelId(culonm);
                    }
                    if (0 != enType) {
                        fieldInfo.setEncyStyleId(enType);
                    }
                }
                //如果存在删除字段，还得将这个字段删除掉，并且这个字段对应的行规则也要删除掉
                deleteOtherField(list, tableFieldInfos);
                tableFieldInfoService.saveOrUpdateBatch(list);

                Date curr = new Date();
                TableRegisterEntity registerEntity = new TableRegisterEntity();
                registerEntity.setTableInfoId(info.getId());
                registerEntity.setBatchNum(curr.getTime());
                registerEntity.setRegisterType(TableRegisterTypeEnum.OFFLINE_UPDATE.getCode());
                long cost = curr.getTime() - startTime;
                registerEntity.setRunTime(curr);
                registerEntity.setCost(cost);
                registerEntity.setRunUser(ShiroUtils.getUserId());
                tableRegisterService.save(registerEntity);

                // 保存物理模型  主题和类目关系
                tableInfoService.saveModelRelation(tableInfo);
                return true;
            }
        } else {
            return false;
        }
    }

    private void deleteOtherField(List<TableFieldInfo> list, List<TableFieldInfo> tableFieldInfos) {
        //如果存在删除字段，还得将这个字段删除掉，并且这个字段对应的行规则也要删除掉
        List<Integer> newTableFieldIds = new ArrayList<>();
        List<Integer> needDelTableFieldIds = new ArrayList<>();
        if (CollectionUtil.isEmpty(list)) {
            //删除所有的需要删除的数据
            if (CollectionUtil.isNotEmpty(tableFieldInfos)) {
                tableFieldInfos.forEach(tableFieldInfo -> {
                    needDelTableFieldIds.add(tableFieldInfo.getId());
                });
            }
        } else {
            if (CollectionUtil.isNotEmpty(tableFieldInfos)) {
                list.forEach(tableFieldInfo -> {
                    if (null != tableFieldInfo.getId()) {
                        newTableFieldIds.add(tableFieldInfo.getId());
                    }
                });
                tableFieldInfos.forEach(tableFieldInfo -> {
                    if (!newTableFieldIds.contains(tableFieldInfo.getId())) {
                        needDelTableFieldIds.add(tableFieldInfo.getId());
                    }
                });
            }
        }
        if (CollectionUtil.isNotEmpty(needDelTableFieldIds)) {
            //删除对应的表的字段和对应的行规则数据
            tableFieldInfoService.deleteByTableFieldIds(needDelTableFieldIds);
        }
    }


    private void checkFieldInfo(List<TableFieldInfo> tableFieldInfos, Integer storeEngine) {
        tableFieldInfos.forEach(f -> {
            if (StringUtils.isNotEmpty(f.getFieldAlias()) && f.getFieldAlias().length() > 100) {
                throw new RRException("字段描述请控制在100字以内");
            }
            if (StringUtils.isNotEmpty(f.getFieldName()) && f.getFieldName().length() > 100) {
                throw new RRException("字段名称请控制在100字以内");
            }
//            f.setFieldName(f.getFieldName().toLowerCase());
            List<String> types = new ArrayList<>();
            if (StorageEngineEnum.HIVE.getCode().equals(storeEngine)) {
                types = HiveTableDataType.getValues();
                //如果不是列表中类型并且不是ARRAY,DECIMAL,MAP开头
                if (!types.contains(f.getFieldType().trim()) && !(f.getFieldType().trim().startsWith("ARRAY") || f.getFieldType().trim().startsWith("DECIMAL") || f.getFieldType().trim().startsWith("MAP"))) {
                    throw new RRException("字段类型不支持，请检查");
                }
            } else {
                types = TableDataType.getValues();
                if (!types.contains(f.getFieldType().trim())) {
                    throw new RRException("字段类型不支持，请检查");
                }
            }
            // f.setFieldName(f.getFieldName().toLowerCase());
        });
    }

    private void checkTableInfo(TableInfo tableInfo) {
        if (null != tableInfo.getTableAlias() && tableInfo.getTableAlias().length() > 100) {
            throw new RRException("表描述请控制在100字以内");
        }
        if (null != tableInfo.getTableName() && tableInfo.getTableName().length() > 255) {
            throw new RRException("表名称请控制在255字以内");
        }
    }

}
